﻿
using System;

namespace FacebookXmpp.Parse
{
	internal class StringParser
    {
        private string _streamText = string.Empty;
        private int _index = 0;

        public void Add(string text)
        {
            if (_index > 0)
            {
                _streamText = _streamText.Substring(_index);
                _index = 0;
            }

            _streamText = _streamText + text;
            IsPaused = false;
        }

        public bool IsPaused { get; private set; }

        private int _mark;
        public bool PauseIfNearEnd(int expect)
        {
            _mark = _index;

            bool comingUpShort = (_index + expect > _streamText.Length);
            if (comingUpShort)
                Pause();

            return comingUpShort;
        }

        public void Pause()
        {
            _index = _mark;
            IsPaused = true;
        }        

        
        public bool IsNext(string text)
        {
            if (_index + text.Length > _streamText.Length)
                return false;

            return string.Compare(_streamText, _index, text, 0, text.Length) == 0;
        }

        public bool IsNext(char c)
        {
            return (_streamText.IndexOf(c, _index) != -1);
        }

        public void Consume(string text)
        {
            _index += text.Length;
        }

        public bool Contains(char c)
        {
            return _streamText.IndexOf(c, _index) != -1;
        }

        public int Find(string find)
        {
            return _streamText.IndexOf(find, _index);
        }

        public char? NextCharOf(params char[] chars)
        {
            int index = _streamText.IndexOfAny(chars, _index);
            if (index == -1)
            {
                Pause();
                return null;
            }

            return _streamText[index];
        }

        public string ConsumeTo(int index)
        {
            if (index > _streamText.Length)
            {
                Pause();
                return string.Empty;
            }

            string ret = _streamText.Substring(_index, index - _index);
            _index = index;
            return ret;
        }

        public string ConsumeTo(char c, bool withTrim)
        {
            int indexOf = _streamText.IndexOf(c, _index);
            if (indexOf == -1)
            {
                Pause();
                return string.Empty;
            }

            string ret = _streamText.Substring(_index, indexOf - _index);
            _index = indexOf;

            if (withTrim)
            {
                SkipWhiteSpace();
                ret = ret.Trim();
            }

            return ret;
        }

        public void SkipWhiteSpace()
        {
            // While index points at whitespace, move to next
            while (_index < _streamText.Length && Char.IsWhiteSpace(_streamText[_index]))
                _index++;

            // If index is at end of the string, empty in the incomming _streamText buffer
            if (_index == _streamText.Length)
            {
                _index = 0;
                _streamText = "";
            }
        }

        public char PeekChar()
        {
            return _streamText[_index];
        }

        public override string ToString()
        {
            int show = _streamText.Length - _index;
            if (show > 100)
                show = 100;

            return _streamText.Substring(_index, show);
        }
    }
}